#include <cutils/cutils.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>

struct PanicHookNode {
	PanicHook hook;
	struct PanicHookNode *next;
};

#define PANIC_HOOK_MAX 64

struct Hooks {
	PanicHook hooks[PANIC_HOOK_MAX];
	size_t len;
};

static struct Hooks HOOKS;

void Panic(char const *message)
{
	for (size_t i = 0; i < HOOKS.len; ++i) {
		HOOKS.hooks[i](message);
	}

	exit(1);
}

void AddPanicHook(PanicHook hook)
{
	if (HOOKS.len >= PANIC_HOOK_MAX) {
		Panic("failed to add panic hook");
		return;
	}

	HOOKS.hooks[HOOKS.len] = hook;
	HOOKS.len += 1;
}

static char const *APPLICATION = NULL;

void VLogging(char const *fmt, va_list ap)
{
	if (APPLICATION == NULL) return;

	fprintf(stderr, "%s: ", APPLICATION);
	vfprintf(stderr, fmt, ap);
	fprintf(stderr, "\n");
	fflush(stderr);
}

void Logging(char const *fmt, ...)
{
	if (APPLICATION == NULL) return;

	va_list ap;
	va_start(ap, fmt);
	VLogging(fmt, ap);
	va_end(ap);
}

static void PanicLoggingHook(char const *message)
{
	Logging("PANIC: %s", message);
}

void LoggingInit(char const *application)
{
	APPLICATION = application;
	AddPanicHook(PanicLoggingHook);
}
